#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json
import logging
import uuid

import tornado.web

logger = logging.getLogger(__name__)


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        remote_ip = self.request.remote_ip
        token = self.request.headers.get['token']


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")


class StatusHandler(tornado.web.RequestHandler):
    def get(self):
        self._rpc_client = self.settings['rpc_client']

        rpc_status = self._rpc_client.status()

        data = {
            'rpc_client': rpc_status
        }

        return self.write(data)


class TaskHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def post(self):
        self._task = None
        self._corr_id = None
        self._queue_name = None
        self._rpc_client = self.settings['rpc_client']

        try:
            data = json.loads(self.request.body.decode('utf-8'))
        except Exception:
            logger.error('json.loads request failed, %s', self.request.body)
            raise tornado.web.HTTPError(400, "bad json")

        self._task = data
        self._corr_id = str(uuid.uuid4())
        self._rpc_client.setup_queue(self.on_queue_declareok)

    def on_queue_declareok(self, frame):
        self._queue_name = frame.method.queue
        # logger.debug('frame=>%s, queue=%s', frame, dir(frame))
        self._rpc_client.bind_queue(self._queue_name, self.on_bindok)

    def on_bindok(self, unused_frame):
        self._rpc_client.setup_consuming(
            self._queue_name, self.on_rpc_response)

        message = json.dumps(self._task, ensure_ascii=False)
        self._rpc_client.publish_message(
            message, self._queue_name, self._corr_id)

    def on_rpc_response(self, unused_channel, basic_deliver, properties, body):
        if self._corr_id == properties.correlation_id:
            resp = json.loads(body.decode('utf-8'))
            self.write(resp)
            self.finish()